package com.hsj.common.gateway.filter;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.druid.util.StringUtils;
import com.hsj.common.gateway.util.RedisUtil;
import com.hsj.common.security.ClientSecurityContext;
import com.hsj.common.security.constants.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Component
public class AuthorizeFilter implements GlobalFilter {


    ExecutorService es = Executors.newFixedThreadPool(5);

    @Autowired
    private RedisUtil redisUtil;

    private static final List<String> excludePathPatterns = new ArrayList<String>(){
        private static final long serialVersionUID = 8687167600818373124L;
        {
            add("/system/login");
            add("/system/logout");
        }
    };

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        // 当前请求地址是否需要登录  true 需要登录
        boolean noLogin = true;
        // 检查请求是否属免登接口
        for (String s : excludePathPatterns) {
            if (s.equalsIgnoreCase(exchange.getRequest().getURI().getPath())) {
                // 放行
                return chain.filter(exchange);
            }
        }

        // 1、获取请求参数
        ServerHttpRequest request = exchange.getRequest();

        // 2、获取Authorization
        String authorization = request.getHeaders().getFirst(SecurityConstants.CLIENT_TOKEN);
        //校验token有效性
        SpringUtil.getBean(ClientSecurityContext.class).tokenValidate(authorization);

        if(StringUtils.isEmpty(authorization)){
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            // 拦截
            return exchange.getResponse().setComplete();
        }

        ServerHttpRequest host = exchange.getRequest().mutate().headers(httpHeaders -> {
            try {
                httpHeaders.add(SecurityConstants.CLIENT_TOKEN, authorization);
            } catch (Exception e) {
            }
        }).build();

        ServerWebExchange build = exchange.mutate().request(host).build();
        // 放行
        return chain.filter(build);
    }
}
